package com.example.demo.game;

import com.example.demo.entity.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

/**
 * @author CY
 * @date 2023/04/03 16:07
 **/
@Component
public class Match {
    private final Queue<User> normalQueue = new LinkedList<>();
    private final Queue<User> highQueue = new LinkedList<>();
    private final Queue<User> veryHighQueue = new LinkedList<>();

    @Autowired
    private OnlineUserMapper onlineUserMapper;
    @Autowired
    private ObjectMapper objectMapper;

    public void add(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.add(user);
                normalQueue.notify();
            }
            System.out.println("把" + user.getUsername() + "放到normalQueue中!");
        } else if (user.getScore() >= 2000 && user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.add(user);
                highQueue.notify();
            }
            System.out.println("把" + user.getUsername() + "放到highQueue中!");

        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.add(user);
                highQueue.notify();
            }
            System.out.println("把" + user.getUsername() + "放到veryHighQueue中!");
        }
    }

    public void remove(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.remove(user);
            }
            System.out.println("把" + user.getUsername() + "移除normalQueue!");
        } else if (user.getScore() >= 2000 && user.getScore() < 3000) {
            synchronized (highQueue) {
                highQueue.remove(user);
            }
            System.out.println("把" + user.getUsername() + "移除highQueue!");

        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.remove(user);
            }
            System.out.println("把" + user.getUsername() + "移除veryHighQueue!");

        }
    }

    public void matcher() {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    scanQueue(normalQueue);
                }
            }
        };
        t1.start();
        Thread t2 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    scanQueue(normalQueue);
                }
            }
        };
        t2.start();

        Thread t3 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    scanQueue(normalQueue);
                }
            }
        };
        t3.start();


    }

    private void scanQueue(Queue<User> queue) throws RuntimeException {
        synchronized (queue) {
            try {
                while (queue.size() < 2) {
                    queue.wait();
                }
                final User user1 = queue.poll();
                final User user2 = queue.poll();
                System.out.println("匹配出两个玩家: " + user1.getUsername() + ", " + user2.getUsername());

                final WebSocketSession session1 = onlineUserMapper.getGameHall(user1.getUserId());
                final WebSocketSession session2 = onlineUserMapper.getGameHall(user2.getUserId());
                if (session1 == null) {
                    queue.add(user2);
                    return;
                }
                if (session2 == null) {
                    queue.add(user1);
                    return;
                }
                if (session2 == session1) {
                    queue.add(user1);
                }

                MatchResponse response1 = new MatchResponse();
                response1.setOk(true);
                response1.setMessage("matchSuccess");
                String json1 = objectMapper.writeValueAsString(response1);
                session1.sendMessage(new TextMessage(json1));

                MatchResponse response2 = new MatchResponse();
                response2.setOk(true);
                response2.setMessage("matchSuccess");
                String json2 = objectMapper.writeValueAsString(response2);
                session2.sendMessage(new TextMessage(json2));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }
}
